/* ThanhVu Nguyen */
/* algorithms with loop invariants - taken from various sources */
/* written in C for compatability with Daikon */

/* Linux: compile with gcc inv.c -o inv -lm -gdwarf-2 */


#include "inv_common.h"
#include "inv_arith_algs1.h"
#include "inv_arith_algs2.h"
#include "inv_knuth.h"
//#include "inv_sting.h"
#include "inv_arrays.h"
#include "inv_miscs.h"
#include "inv_seeded_bugs.h"

/***** Driver *****/
int main(int argc, char **argv){
  int i ;
  srand((unsigned int)time(0));

  init_tracker();


  printf("#cmd: ");

  for (i=0; i < argc ; ++i){
    printf("%s ", argv[i]);
  }
  printf("\n");


  if (argc >= 2 ){
    if (strcmp(argv[1],"myisprime")==0){
      printf("#result = %d\n", myisprime(atoi(argv[2])));
    }
    else if (strcmp(argv[1],"randrange_f")==0){
      for(i=0; i < 100 ; ++i){
        printf("#result = %g\n", 
               randrange_f(atof(argv[2]),atof(argv[3]),TRUE));
      }
    }
    else if (strcmp(argv[1],"cohendiv")==0){
      printf("#result = %d\n", 
             cohendiv(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"divbin")==0){
      printf("#result = %d\n", 
             divbin(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"hard")==0){
      printf("#result = %d\n", 
             hard(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"mannadiv")==0){
      printf("#result = %d\n", 
             mannadiv(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"wensley")==0){
      printf("#result = %g\n", 
             wensley(atof(argv[2]),atof(argv[3]),atof(argv[4])));
    }
    else if (strcmp(argv[1],"freire2")==0){
      printf("#result = %d\n", freire2(atof(argv[2])));
    }
    else if (strcmp(argv[1],"freire1")==0){
      printf("#result = %d\n", freire1(atof(argv[2])));
    }
    else if (strcmp(argv[1],"sqrt1")==0){
      printf("#result = %d\n", sqrt1(atoi(argv[2])));
    }
    else if (strcmp(argv[1],"dijkstra")==0){
      printf("#result = %d\n", dijkstra(atoi(argv[2])));
    }
    else if (strcmp(argv[1],"z3sqrt")==0){
      printf("#result = %g\n", 
             z3sqrt(atof(argv[2]), atof(argv[3])));
    }
    else if (strcmp(argv[1],"euclidex1")==0){
      printf("#result = %d\n", 
             euclidex1(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"euclidex2")==0){
      printf("#result = %d\n", 
             euclidex2(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"euclidex3")==0){
      printf("#result = %d\n", 
             euclidex3(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"lcm1")==0){
      printf("#result = %d\n", 
             lcm1(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"lcm2")==0){
      printf("#result = %d\n", 
             lcm2(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"prodbin")==0){
      printf("#result = %d\n", 
             prodbin(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"prod4br")==0){
      printf("#result = %d\n", 
             prod4br(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"fermat1")==0){
      printf("#result = %d\n", 
             fermat1(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"fermat2")==0){
      printf("#result = %d\n", 
             fermat2(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"knuth")==0){
      printf("#result = %d\n", 
             knuth(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"cohencu")==0){
      printf("#result = %d\n", 
             cohencu(atoi(argv[2])));
    }
    else if (strcmp(argv[1],"f1")==0){
      printf("#result = %d\n", 
             f1(atoi(argv[2])));
    }
    else if (strcmp(argv[1],"readers_writers")==0){
      printf("#result = %d\n", 
             readers_writers(atoi(argv[2]),
                             atoi(argv[3]),atoi(argv[4])));
    }
    else if (strcmp(argv[1],"geo2")==0){
      printf("#result = %d\n", 
             geo2(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"geo3")==0){
      printf("#result = %d\n", 
             geo3(atoi(argv[2]),atoi(argv[3]),atoi(argv[4])));
    }
    else if (strcmp(argv[1],"ps2")==0){
      printf("#result = %d\n", ps2(atoi(argv[2])));
    }
    else if (strcmp(argv[1],"ps3")==0){
      printf("#result = %d\n", ps3(atoi(argv[2])));
    }
    else if (strcmp(argv[1],"ps4")==0){
      printf("#result = %d\n", ps4(atoi(argv[2])));
    }
    
    //STING
    /* else if (strcmp(argv[1],"seesaw")==0){ */
    /*   printf("#result = %d\n", seesaw(atoi(argv[2]))); */
    /* } */
    /* else if (strcmp(argv[1],"robot")==0){ */
    /*   printf("#result = %d\n", robot(atoi(argv[2]))); */
    /* } */
    /* else if (strcmp(argv[1],"berkeley")==0){ */
    /*   printf("#result = %d\n",  */
    /*          berkeley(atoi(argv[2]),atoi(argv[3]), */
    /*                   atoi(argv[4]),atoi(argv[5]))); */
    /* } */
    /* else if (strcmp(argv[1],"berkeley_nat")==0){ */
    /*   printf("#result = %d\n",  */
    /*          berkeley(atoi(argv[2]),atoi(argv[3]), */
    /*                   atoi(argv[4]),atoi(argv[5]))); */
    /* } */
    /* else if (strcmp(argv[1],"heap")==0){ */
    /*   printf("#result = %d\n",  */
    /*          heap(atoi(argv[2]), atoi(argv[3]))); */
    /* } */
    /* else if (strcmp(argv[1],"efm")==0){ */
    /*   printf("#result = %d\n",  */
    /*          efm(atoi(argv[2]),atoi(argv[3]),atoi(argv[4]), */
    /*              atoi(argv[5]),atoi(argv[6]),atoi(argv[7]) */
    /*              )); */
    /* } */
    /* else if (strcmp(argv[1],"efm1")==0){ */
    /*   printf("#result = %d\n",  */
    /*          efm1(atoi(argv[2]),atoi(argv[3]),atoi(argv[4]), */
    /*              atoi(argv[5]),atoi(argv[6]),atoi(argv[7]) */
    /*              )); */

    /* } */
    /* else if (strcmp(argv[1],"lifo")==0){ */
    /*   printf("#result = %d\n", lifo(atoi(argv[2]))); */
    /* } */
    /* else if (strcmp(argv[1],"lifo_nat")==0){ */
    /*   printf("#result = %d\n", lifo_nat(atoi(argv[2]))); */
    /* } */
    /* else if (strcmp(argv[1],"cars_midpt")==0){ */
    /*   printf("#result = %d\n",  */
    /*          cars_midpt(atoi(argv[2]),atoi(argv[3]),atoi(argv[4]))); */
    /* } */
    /* else if (strcmp(argv[1],"swim_pool")==0){ */
    /*   printf("#result = %d\n",  */
    /*          swim_pool(atoi(argv[2]),atoi(argv[3]))); */
    /* } */
    /* else if (strcmp(argv[1],"swim_pool1")==0){ */
    /*   printf("#result = %d\n",  */
    /*          swim_pool1(atoi(argv[2]),atoi(argv[3]))); */
    /* } */
    /* else if (strcmp(argv[1],"schedule2p")==0){ */
    /*   printf("#result = %d\n", schedule2p(atoi(argv[2]))); */
    /* } */
    /* else if (strcmp(argv[1],"train_rm03")==0){ */
    /*   printf("#result = %d\n",  */
    /*          train_rm03(atoi(argv[2]),atoi(argv[3]),atoi(argv[4]),atoi(argv[5]),atoi(argv[6]))); */
    /* } */
    /* else if (strcmp(argv[1],"cars2p")==0){ */
    /*   printf("#result = %d\n", cars2p(atoi(argv[2]))); */
    /* } */
    /* else if (strcmp(argv[1],"cars3p")==0){ */
    /*   printf("#result = %d\n", cars3p(atoi(argv[2]))); */
    /* } */
    /* else if (strcmp(argv[1],"cars4p")==0){ */
    /*   printf("#result = %d\n", cars4p(atoi(argv[2]))); */
    /* } */

    //MISCS
    else if (strcmp(argv[1],"daikon_test")==0){
      printf("#result = %d\n", daikon_test(atoi(argv[2])));
    }
    /* else if (strcmp(argv[1],"myheapsort")==0){ */
    /*   printf("#result = %d\n", myheapsort(atoi(argv[2]))); */
    /* } */
    else if (strcmp(argv[1],"knuth_gcd_euclid")==0){
      printf("#result = %d\n", knuth_gcd_euclid(atoi(argv[2]),atoi(argv[3])));
    }
    else if (strcmp(argv[1],"knuth_gcd_bin")==0){
      printf("#result = %d\n", knuth_gcd_bin(atoi(argv[2]),atoi(argv[3])));
    }
    else if(strcmp(argv[1],"knuth_gcd_n")==0){
      int size = argc-2;
      int *arr = (int *)malloc(sizeof(int[size]));
      int i = 0;
      for(i = 0; i < size; ++i){arr[i]=atoi(argv[2+i]);}
      
      printf("#result = %d\n", knuth_gcd_n(arr,size));
      free(arr);
    }
    else if (strcmp(argv[1],"knuth_factor_fermat")==0){
      printf("#result = %d\n", knuth_factor_fermat(atoi(argv[2])));
    }
    else if (strcmp(argv[1],"knuth_factor_rho")==0){
      printf("#result = %d\n", knuth_factor_rho(atoi(argv[2])));
    }

    else if (strcmp(argv[1],"nr_diophantian")==0){
      printf("#result = %d\n", 
             nr_diophantian(atof(argv[2]),atof(argv[3]),atof(argv[4])));
    }

    else if (strcmp(argv[1],"nr_prime")==0){
      printf("#result = %d\n", 
             nr_prime(atof(argv[2])));
    }
    else if (strcmp(argv[1],"nr_factors")==0){
      printf("#result = %d\n", 
             nr_factors(atof(argv[2])));
    }


    //MISCS
    else if (strcmp(argv[1],"high_filter1")==0){
      printf("#results = %g\n",high_filter1(atof(argv[2]),atof(argv[3])));
    }
    else if (strcmp(argv[1],"high_filter2")==0){
      printf("#results = %g\n",high_filter2(atof(argv[2]),atof(argv[3])));
    }
    
    
    //BUGS

    else if (strcmp(argv[1],"euclidex2_bug")==0){
      printf("#result = %d\n", 
             euclidex2_bug(atoi(argv[2]),atoi(argv[3])));
    }


    else{
      printf("unrecognized program \'%s\'\n", argv[1]);
    }


  }
  
  
  
  clean_tracker();
  return 0;
}

